﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

using TowerDef_s_enseLibrary.game;

namespace TowerDef_s_enseLibrary.gui
{
    /// <summary>
    /// Describes the state of the button
    /// </summary>
    public enum ButtonStatus
    {
        Normal,
        MouseOver,
        Pressed,
    }

    public class Button : Sprite
    {
        #region variables

        // Store the MouseState of the last frame
        private MouseState _previousState;

        // The the different _state textures
        private Texture2D _hoverTexture;
        private Texture2D _pressedTexture;

        // A rectangle that covers the button
        private Rectangle _bounds;

        // Store the current _state of the button
        private ButtonStatus _state = ButtonStatus.Normal;

        #endregion variables

        #region functions

        /// <summary>
        /// Creates a new button
        /// </summary>
        /// <param name="texture">The normal button Texture for the button</param>
        /// <param name="hoverTexture">The Texture drawn when the mouse is over the button</param>
        /// <param name="pressedTexture">The Texture drawn when the button has been pressed</param>
        /// <param name="position">The position where the button will be drawn</param>
        public Button(Texture2D texture, Texture2D hoverTexture, Texture2D pressedTexture, Vector2 position) : base(texture, position)
        {
            this._hoverTexture = hoverTexture;
            this._pressedTexture = pressedTexture;
            this._bounds = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
        }

        /// <summary>
        /// Updates the buttons _state
        /// </summary>
        /// <param name="gameTime">The current game time</param>
        public override void Update(GameTime gameTime)
        {
            // Determine if the mouse is over the button
            MouseState mouseState = Mouse.GetState();

            int mouseX = mouseState.X;
            int mouseY = mouseState.Y;

            bool isMouseOver = _bounds.Contains(mouseX, mouseY);

            if(isMouseOver && _state != ButtonStatus.Pressed)
            {
                _state = ButtonStatus.MouseOver;
            }
            else if(isMouseOver == false && _state != ButtonStatus.Pressed)
            {
                _state = ButtonStatus.Normal;
            }

            // Check if the player holds down the button
            if(mouseState.LeftButton == ButtonState.Pressed &&
             _previousState.LeftButton == ButtonState.Released)
            {
                if(isMouseOver == true)
                {
                    // Update the button _state
                    _state = ButtonStatus.Pressed;
                    if(OnPress != null)
                    {
                        // Fire the OnPress event
                        OnPress(this, EventArgs.Empty);
                    }
                }
            }

            // Check if the player releases the button
            if(mouseState.LeftButton == ButtonState.Released &&
             _previousState.LeftButton == ButtonState.Pressed)
            {
                if(isMouseOver == true)
                {
                    // update the button _state
                    _state = ButtonStatus.MouseOver;

                    if(Clicked != null)
                    {
                        // Fire the clicked event
                        Clicked(this, EventArgs.Empty);
                    }
                }

                else if(_state == ButtonStatus.Pressed)
                {
                    _state = ButtonStatus.Normal;
                }
            }

            _previousState = mouseState;
        }

        /// <summary>
        /// Draws the button
        /// </summary>
        /// <param name="spriteBatch">A group of sprite settings</param>
        public override void Draw(SpriteBatch spriteBatch)
        {
            switch(_state)
            {
                case ButtonStatus.Normal:
                    spriteBatch.Draw(Texture, _bounds, Color.White);
                    break;
                case ButtonStatus.MouseOver:
                    spriteBatch.Draw(_hoverTexture, _bounds, Color.White);
                    break;
                case ButtonStatus.Pressed:
                    spriteBatch.Draw(_pressedTexture, _bounds, Color.White);
                    break;
                default:
                    spriteBatch.Draw(Texture, _bounds, Color.White);
                    break;
            }
        }

        #endregion functions

        #region events

        // Gets fired when the button is pressed
        public event EventHandler Clicked;
        // Gets fired when the button is held down
        public event EventHandler OnPress;

        #endregion events
    }
}
